﻿define([
    "dojo/_base/declare", "esri/layers/GraphicsLayer", 'esri/geometry/Point'
], function(declare, GraphicsLayer) {
    var EsriJSONLayer = GraphicsLayer.createSubclass({
        setData: function(mapView, layer) {
            var me = this;
            if (!mapView) {
                return
            };
            me.mapView = mapView;
            let mapUtils = me.mapUtils = mapView.mapUtils;
            var options = layer.layer || {};
            if (!options.url) {
                return;
            }
            var symbolFieldName = options.symbolFieldName || mapView.getSymbolFieldName();
            me.symbolFieldName = symbolFieldName;


            var sysObj = {
                esriGeometryPoint: {
                    color: [255, 0, 0, 128],
                    size: 12,
                    angle: 0,
                    xoffset: 0,
                    yoffset: 0,
                    type: "simplePoint",
                    style: 'circle',
                    outline: {
                        color: [0, 0, 0, 255],
                        width: 1,
                        style: 'solid'
                    }
                },
                esriGeometryPoint_image: {
                    type: 'imagePoint'
                },
                esriGeometryPolyline: {
                    color: [0, 0, 0, 255],
                    width: 1,
                    type: "simplePolyline",
                    style: 'solid'
                },
                esriGeometryPolygon: {
                    color: [255, 0, 0, 20],
                    outline: {
                        color: [255, 0, 0, 255],
                        width: 1,
                        style: "solid"
                    },
                    type: "simplePolygon",
                    style: "solid"
                }
            };
            me.sysObj = sysObj;
            // me.type = {
            //     simplePoint: 'esriSMS',
            //     imagePoint: 'esriPMS',
            //     simplePolyline: 'esriSLS',
            //     simplePolygon: 'esriSFS'
            // };
            me.simpleImage_style = {};
            me.simplePoint_style = {
                'esriSMSCircle': 'circle',
                'esriSMSCross': 'cross',
                'esriSMSDiamond': 'diamond',
                'esriSMSSquare': 'square',
                'esriSMSX': 'x'
            };
            me.simplePolyline_style = {
                'esriSLSSolid': 'solid',
                'esriSLSDash': 'dash',
                'esriSLSDashDot': 'dashdot',
                'esriSLSLongDashDotDot': 'longdashdotdot',
                'esriSLSDot': 'dot',
                'esriSLSLongDash': 'longdash',
                'esriSLSLongDashDot': 'longdashdot',
                'esriSLSNull': 'none',
                'esriSLSShortDash': 'shortdash',
                'esriSLSShortDashDot': 'shortdashdot',
                'esriSLSShortDashDotDot': 'shortdashdotdot',
                'esriSLSShortDot': 'shortdot'
            };
            me.simplePolygon_style = {
                'esriSFSSolid': 'solid',
                'esriSFSCross': 'cross',
                'esriSFSDiagonal': 'diagonal',
                'esriSFSDiagonalCross': 'diagonalCross',
                'esriSFSForwardDiagonal': 'forwardDiagonal',
                'esriSFSHorizontal': 'horizontal',
                'esriSFSNull': 'none',
                'esriSFSVertical': 'vertical'
            };

            mapUtils.$.ajax({
                url: options.url,
                success: function(res) {
                    if (typeof res == 'string') {
                        res = JSON.parse(res);
                    };
                    var symbol = sysObj[res.geometryType];
                    if (typeof options[symbolFieldName] == 'string') {
                        symbol = options[symbolFieldName];
                        mapUtils.getSymbol(mapView, symbol, function(symbol) {
                            me._callback(res, symbol, layer)
                        });
                    } else {
                        if (!res.geometryType) {
                            console.error('geometryType error');
                            return;
                        }
                        symbol = mapUtils.$.extend(true, sysObj[res.geometryType], options[symbolFieldName]);
                        var sys = mapUtils.createSymbol(mapView, symbol);
                        me._callback(res, sys, layer);
                    };
                },
                error: function(err) {
                    console.log(options.url)
                    console.error('EsriJsonLayer请求json地址报错！');
                }
            })
        },
        coordinateConvert: function(feature, coordinateConvert, geometryType) {
            var me = this;
            var geo = feature.geometry;
            switch (geometryType) {
                case 'esriGeometryPolygon':
                    var rings = geo.rings;
                    for (let i = 0; i < rings.length; i++) {
                        let ring = rings[i];
                        for (let g = 0; g < ring.length; g++) {
                            let obj = me.mapUtils[coordinateConvert]({ x: ring[g][0], y: ring[g][1] });
                            ring[g] = [obj.x, obj.y];
                        };
                    };
                    break;
                case 'esriGeometryPolyline':
                    var paths = geo.paths;
                    for (let i = 0; i < paths.length; i++) {
                        let path = paths[i];
                        for (let g = 0; g < path.length; g++) {
                            let obj = me.mapUtils[coordinateConvert]({ x: path[g][0], y: path[g][1] });
                            path[g] = [obj.x, obj.y];
                        };
                    };
                    break;
                case 'esriGeometryPoint':
                    let obj = me.mapUtils[coordinateConvert]({ x: geo.x, y: geo.y });
                    feature.geometry.x = obj.x;
                    feature.geometry.y = obj.y;
                    break;
            };
        },
        _callback: function(res, symbol, options) {
            var me = this;
            res.features.map(function(feature, index) {
                feature.geometry.spatialReference = feature.spatialReference || res.spatialReference;
                if (feature.symbol) {
                    feature.symbol.type = me.sysObj[res.geometryType] ? me.sysObj[res.geometryType].type : '';
                    if (feature.symbol.style) {
                        feature.symbol.style = me[feature.symbol.type + '_style'][feature.symbol.style];
                    };

                    symbol = me.mapUtils.createSymbol(me.mapView, feature.symbol);
                };
                if (options.coordinateConvert) {
                    me.coordinateConvert(feature, options.coordinateConvert, res.geometryType);
                };
                feature.symbol = symbol;
                if (res.geometryType == "esriGeometryPoint") {
                    feature.geometry = me.mapUtils.createPoint(me.mapView, feature.geometry);
                } else if (res.geometryType == "esriGeometryPolyline") {
                    feature.geometry = me.mapUtils.createPolyline(me.mapView, feature.geometry);
                } else if (res.geometryType == "esriGeometryPolygon") {
                    feature.geometry = me.mapUtils.createPolygon(me.mapView, feature.geometry);
                };

                var graphic = me.mapUtils.createGraphic(me.mapView, feature)
                me.add(graphic);
                if (index == res.features.length - 1) {
                    if ($.isFunction(options.callback)) {
                        options.callback(me);
                    }
                }
            });

        },
        getGraphicLocation: function(mapView, esriEvent, mapUtils) {
            var me = this;
            var location = null;

            var _geometryType = esriEvent.graphic.geometry.type;
            switch (_geometryType) {
                case mapUtils.Enum.GType.Point:
                    location = me.getPointGraphicLocation(mapView, esriEvent);
                    break;
                case mapUtils.Enum.GType.Polyline:
                    location = me.getPolylineGraphicLocation(mapView, esriEvent);
                    break;
                case mapUtils.Enum.GType.Extent:
                case mapUtils.Enum.GType.Circle:
                case mapUtils.Enum.GType.Polygon:
                    location = me.getPolygonGraphicLocation(mapView, esriEvent);
                    break;
                case mapUtils.Enum.GType.Text:
                    location = me.getTextGraphicLocation(mapView, esriEvent);
                    break;
            };
            return location;
        },
        getPointGraphicLocation: function(mapView, esriEvent) {
            if (!esriEvent || !esriEvent.graphic) {
                return;
            }
            var geometry = esriEvent.graphic.geometry || {};

            var lngFieldName = mapView.getLngFieldName();
            var latFieldName = mapView.getLatFieldName();
            var location = {};
            location[lngFieldName] = geometry.x;
            location[latFieldName] = geometry.y;
            return location;
        },
        getPolylineGraphicLocation: function(mapView, esriEvent) {
            if (!esriEvent || !esriEvent.mapPoint) {
                return;
            }
            var geometry = esriEvent.mapPoint || {};

            var lngFieldName = mapView.getLngFieldName();
            var latFieldName = mapView.getLatFieldName();
            var location = {};
            location[lngFieldName] = geometry.x;
            location[latFieldName] = geometry.y;
            return location;
        },
        getPolygonGraphicLocation: function(mapView, esriEvent) {
            if (!esriEvent || !esriEvent.mapPoint) {
                return;
            }
            var geometry = esriEvent.mapPoint || {};
            var lngFieldName = mapView.getLngFieldName();
            var latFieldName = mapView.getLatFieldName();
            var location = {}
            location[lngFieldName] = geometry.x;
            location[latFieldName] = geometry.y;
            return location;
        },
        getTextGraphicLocation: function(mapView, esriEvent) {
            if (!esriEvent || !esriEvent.graphic) {
                return;
            }
            var geometry = esriEvent.graphic.geometry || {};

            var lngFieldName = mapView.getLngFieldName();
            var latFieldName = mapView.getLatFieldName();
            var location = {};
            location[lngFieldName] = geometry.x;
            location[latFieldName] = geometry.y;
            return location;
        }
    });
    return EsriJSONLayer;
});